package com.twotwoshop.service.chat.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.twotwoshop.commom.redis.RedisConstants;
import com.twotwoshop.domin.chat.dtos.ChatMessageDto;
import com.twotwoshop.domin.chat.pojo.ChatMessage;
import com.twotwoshop.domin.chat.vos.ChatMessageDetilVo;
import com.twotwoshop.domin.chat.vos.ChatMessageVo;
import com.twotwoshop.domin.common.dtos.PageResponseResult;
import com.twotwoshop.domin.common.dtos.ResponseResult;
import com.twotwoshop.domin.common.enums.AppHttpCodeEnum;
import com.twotwoshop.domin.goods.pojo.Product;
import com.twotwoshop.domin.user.pojos.ApUser;
import com.twotwoshop.fegin.api.user.IUserClient;
import com.twotwoshop.service.chat.mapper.ChatMapper;
import com.twotwoshop.service.chat.service.ChatService;
import com.twotwoshop.util.thread.AppThreadLocalUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
@RequiredArgsConstructor
public class ChatServiceImpl extends ServiceImpl<ChatMapper, ChatMessage> implements ChatService {

    private final ChatMapper chatMapper;

    private final IUserClient userClient;

    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 获取聊天记录历史
     *
     * @param chatMessageDto
     * @return
     */
    @Override
    public ResponseResult getHistoryMessages(ChatMessageDto chatMessageDto) {

        //1.检查参数
        if (chatMessageDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }

        ResponseResult responseResult = new ResponseResult();

        //2.构建分页查询
        // 2.创建分页对象
        IPage<ChatMessage> page = new Page<>(chatMessageDto.getPage(), chatMessageDto.getSize());


        //3.获取当前用户id
        Integer userId = AppThreadLocalUtil.getUser().getId();


        //3.构建查询条件
        LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w
                .and(subW -> subW
                        .eq(ChatMessage::getSenderId, userId)
                        .eq(ChatMessage::getReceiverId, chatMessageDto.getReceiverId())
                ).or(subW -> subW
                        .eq(ChatMessage::getSenderId, chatMessageDto.getReceiverId())
                        .eq(ChatMessage::getReceiverId, userId)
                )
        );


        //4.如果有商品ID，添加商品过滤条件
        if(chatMessageDto.getGoodsId() != null) {
            wrapper.eq(ChatMessage::getGoodsId, chatMessageDto.getGoodsId());
        }

        //早发的早输出
        wrapper.orderByAsc(ChatMessage::getCreateTime);

        //查询商品信息
        page = chatMapper.selectPage(page, wrapper);

        if(page.getRecords()==null || page.getRecords().size()==0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"获取聊天记录失败");
        }


        //获取聊天列表    // TODO 发送者发送给接收者的信息 接收者查询后 将发送者发送给接收者的信息设置为已读
        List<ChatMessage> chatMessageList = page.getRecords();
        for(ChatMessage chatMessage : chatMessageList) {

            if(chatMessage.getReceiverId()==userId.longValue()) {
                //查到聊天记录后设置为已读
                chatMessage.setIsRead(true);
            }


            chatMapper.updateById(chatMessage);
        }


        ChatMessageDetilVo chatMessageDetilVo = new ChatMessageDetilVo();

        //查询发布商品人的昵称和头像
        ResponseResult userInfo = userClient.getUserInfoById(chatMessageDto.getReceiverId());
        if (userInfo.getCode()==200){
            //拿取用户信息
            String jsonString = JSONUtil.toJsonStr(userInfo.getData());
            ApUser user = JSONUtil.toBean(jsonString, ApUser.class);

            //设置用户的名称和头像
            /*vo.setName(user.getName());*/
            chatMessageDetilVo.setSenderAvatar(user.getImage());
           /* vo.setUserId(user.getId().longValue());*/
        }

        //包含对方头像的返回结果
        chatMessageDetilVo.setChatMessageList(chatMessageList);

        //3.结果返回
        responseResult = new PageResponseResult(chatMessageDto.getPage(), chatMessageDto.getSize(), (int) page.getTotal());
        responseResult.setData(chatMessageList);


        return responseResult;
    }


    /**
     * 获取聊天列表
     *
     * @return
     */
    @Override
    public ResponseResult getMessagesList() {

        //1.获取当前用户
        Integer userId = AppThreadLocalUtil.getUser().getId();


        LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<>();
        //接收者
        wrapper.eq(ChatMessage::getReceiverId, userId)
        //是否可见
                .eq(ChatMessage::getIs_visible,true)
        //顺序排列
                .orderByAsc(ChatMessage::getCreateTime);



        //2.获取聊天列表
        List<ChatMessage> chatMessageList = chatMapper.selectList(wrapper);
/*        private Long id; //#

        private Long senderId;      // 发送者ID #
        private Long receiverId;    // 接收者ID  #
        private Long goodsId;       // 商品ID  #
        private String content;     // 消息内容  #
        private Integer type;       // 消息类型(0:文本 1:图片)
        private Boolean isRead;     // 是否已读  #
        private Date createTime;    // 发送时间  #*/


        // 使用Stream API处理
        Map<Long, Map<Long, Optional<ChatMessage>>> latestMessagesPerSenderIdAndGoodsId = chatMessageList.stream()
                // 先按照senderId进行分组
                .collect(Collectors.groupingBy(
                        ChatMessage::getSenderId,
                        // 对于每个senderId，再按照goodsId进行分组
                        Collectors.groupingBy(
                                ChatMessage::getGoodsId,
                                // 在每个senderId和goodsId的组内，获取创建时间最晚的ChatMessage
                                Collectors.reducing((msg1, msg2) -> msg1.getCreateTime().after(msg2.getCreateTime()) ? msg1 : msg2)
                        )
                ));

        // 将结果转换为一个列表
        List<ChatMessage> resultChatMessage = latestMessagesPerSenderIdAndGoodsId.values().stream()
                // 对每个内层Map进行流操作
                .flatMap(map -> map.values().stream())
                // 过滤掉空的Optional值（理论上不会发生，因为每个senderId和goodsId组合至少有一个ChatMessage）
                .filter(Optional::isPresent)
                // 获取Optional中的ChatMessage对象
                .map(Optional::get)
                // 收集结果
                .collect(Collectors.toList());

        //返会的数据Vo
        List<ChatMessageVo> chatMessageVoList = new ArrayList<>();


        //拼装数据
        for (ChatMessage chatMessage : resultChatMessage) {

            //    "id": "会话ID",
            //   "senderId": "发送者用户ID",
            //   "goodsId": "商品ID",
            ChatMessageVo chatMessageVo = BeanUtil.copyProperties(chatMessage, ChatMessageVo.class);

            //   "lastTime": "最后消息时间戳",
            chatMessageVo.setLastTime(chatMessage.getCreateTime());

            //   "lastMessage": "最后一条消息内容",
            chatMessageVo.setLastMessage(chatMessage.getContent());

            //用户调用
            //   "senderName": "发送者昵称",
            //   "senderAvatar": "发送者头像URL",
            //获取发送者的个人信息
            ResponseResult userInfoById = userClient.getUserInfoById(chatMessageVo.getSenderId());
            if (userInfoById.getCode()==200){

                //拿取用户信息
                String jsonString = JSONUtil.toJsonStr(userInfoById.getData());
                ApUser user = JSONUtil.toBean(jsonString, ApUser.class);

                // senderName: 发送消息用户的昵称
                chatMessageVo.setSenderName(user.getName());

                //senderAvatar: 发送消息用户的头像
                chatMessageVo.setSenderAvatar(user.getImage());
            }

            //   "unreadCount": "未读消息数量"
            LambdaQueryWrapper <ChatMessage>queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ChatMessage::getReceiverId, chatMessage.getReceiverId())
            .eq(ChatMessage::getSenderId, chatMessage.getSenderId())
                    .eq(ChatMessage::getGoodsId, chatMessage.getGoodsId())
                    .eq(ChatMessage::getIsRead,0);

            Long isReadCount = chatMapper.selectCount(queryWrapper);

            chatMessageVo.setUnreadCount(isReadCount.intValue());

            //商品调用
            //   "goodsTitle": "商品标题",
            //   "goodsImage": "商品图片URL",
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(RedisConstants.GOODS_DETAIILS_KEY + chatMessage.getGoodsId());
            if (entries != null && entries.size() > 0) {
                Product product = new Product();
                BeanUtil.fillBeanWithMap(entries,product,true);

                //   "goodsTitle": "商品标题",
                chatMessageVo.setGoodsTitle(product.getTitle());

                //将图片路径转化为集合
                List<String> imageList = Arrays.stream(product.getImages().split(","))
                        .map(String::trim)
                        .collect(Collectors.toList());


                // 使用 replace 方法去除方括号
                String imageUrl = imageList.get(0).toString().replace("[", "").replace("]", "");

                log.error(imageUrl);

                //   "goodsImage": "商品图片URL",
                chatMessageVo.setGoodsImage(imageUrl);
            }

            chatMessageVoList.add(chatMessageVo);

        }




        return ResponseResult.okResult(chatMessageVoList);
    }



    /**
     * 获取未读消息数量
     *
     * @return
     */
    @Override
    public ResponseResult getMessagesCountList() {


        //1.获取当前用户
        Integer userId = AppThreadLocalUtil.getUser().getId();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }


        LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<>();
        //接收者
        wrapper.eq(ChatMessage::getReceiverId, userId)
                //未读消息
                .eq(ChatMessage::getIsRead,0);
                //顺序排列


        Long unRreadMessageCount = chatMapper.selectCount(wrapper);
        if(unRreadMessageCount==0) {
            return ResponseResult.okResult(0);
        }

        return ResponseResult.okResult(unRreadMessageCount);
    }

    /**
     * 删除某一条聊天
     *
     * @return
     */
    @Override
    public ResponseResult removeMessages(ChatMessageDto chatMessageDto) {

        //1.检查参数
        if (chatMessageDto == null || chatMessageDto.getSessionId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"删除聊天的id为空");
        }

        //2.构造查询条件
        LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatMessage::getReceiverId, chatMessageDto.getReceiverId())
                .eq(ChatMessage::getSenderId,chatMessageDto.getSenderId())
                .eq(ChatMessage::getGoodsId,chatMessageDto.getGoodsId())
                .eq(ChatMessage::getIs_visible,true);

        //2.查询该聊天列表是否存在
        List<ChatMessage> chatMessageList = chatMapper.selectList(wrapper);
        if (chatMessageList == null || chatMessageList.size() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"删除聊天列表不存在");
        }

        List<Long> messageId = chatMessageList.stream().map(ChatMessage::getId).collect(Collectors.toList());

        if (messageId == null || messageId.size() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"会话id收集失败");
        }

        //3.列表存在 设置为设置者不可见
        chatMapper.updateMessagesVisibility(messageId);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
























